<template>
  <div
    class="derOnlyOneContainer _containers"
    :style="{
      transformOrigin: 'top left',
      left: `${left}px`,
      top: `${top}px`,
    }"
  >
    <!-- <div class="title">
      <div class="time_title">计算器</div>
      <div class="time_close" @click="close" @touchstart.prevent="close">
        <img :src="closeIcon" />
      </div>
    </div> -->

    <div id="calculator">
      <!--显示框-->
      <el-input id="input-box" v-model="inputShow.value" :disabled="true" style="width: 70%" />
      <div id="btn-list">
        <div class="btn-30 btn-radius color-red clear-marginleft" @click="clearValue()">C</div>
        <div class="btn-30 btn-radius color-blue" @click="oppositeValue()">+/-</div>
        <div class="btn-30 btn-radius color-blue" @click="inputValue('%')">%</div>
        <div class="btn-70 btn-radius color-blue font-14" @click="backValue()">←</div>
        <div class="btn-30 btn-radius clear-marginleft" @click="inputValue('7')">7</div>
        <div class="btn-30 btn-radius" @click="inputValue('8')">8</div>
        <div class="btn-30 btn-radius" @click="inputValue('9')">9</div>
        <div class="btn-30 btn-radius color-blue font-14" @click="squareValue()">×²</div>
        <div class="btn-30 btn-radius color-blue font-12" @click="radicalValue()">√</div>
        <div class="btn-30 btn-radius clear-marginleft" @click="inputValue('4')">4</div>
        <div class="btn-30 btn-radius" @click="inputValue('5')">5</div>
        <div class="btn-30 btn-radius" @click="inputValue('6')">6</div>
        <div class="btn-30 btn-radius color-blue font-14" @click="inputValue('×')">×</div>
        <div class="btn-30 btn-radius color-blue font-12" @click="inputValue('÷')">÷</div>
        <div class="btn-30 btn-radius clear-marginleft" @click="inputValue('1')">1</div>
        <div class="btn-30 btn-radius" @click="inputValue('2')">2</div>
        <div class="btn-30 btn-radius" @click="inputValue('3')">3</div>
        <div class="btn-30 btn-radius color-blue font-14" @click="inputValue('+')">+</div>
        <div class="btn-30 btn-radius color-blue font-14" @click="inputValue('-')">-</div>
        <div class="btn-70 btn-radius clear-marginleft" @click="inputValue('0')">0</div>
        <div class="btn-30 btn-radius" @click="inputValue('.')">.</div>
        <div class="btn-70 btn-radius color-blue font-14" @click="calValue()">=</div>
      </div>
    </div>
    <Title title="计算器" @close="close" @getPosition="getPosition" />
  </div>
</template>

<script>
import closeIcon from '../../../assets/teaching/close.svg';
import Title from '../panel/title.vue';

export default {
  components: { Title },
  props: { value: Boolean },
  data() {
    return {
      inputShow: {
        value: '0',
      },
      closeIcon,
      left: 0,
      top: 0,
    };
  },
  watch: {},
  created() {},

  methods: {
    // Title 组件返回的 x, y值
    getPosition({ x, y }) {
      this.left = x;
      this.top = y;
    },
    close() {
      this.$emit('close');
    },

    inputValue(param) {
      /* if (Object.prototype.toString.call(this.inputShow.value) === '[object Number]') { // 判断输入框内容是否为数字类型
        this.inputShow.value = '0'; // 数字类型说明是上个计算结果,清空内容
      } */
      const str = `${this.inputShow.value}`; // 输入内容时,将输入框内容转为字符串类型
      const len = str.length;
      const arr = ['+', '-', '×', '÷'];
      // parseInt(str.split('').reverse().join('')))是获取输入框内最后一串数字,再反转回来 ,num为输入框内最后一串数字
      const num = `${parseFloat(str.split('').reverse().join(''))}`.split('').reverse().join('');
      const nlen = num.length;
      // 输入框内最后一串数字不为0时拼接字符串(最后一个判断是让0.几的数进入下面的拼接)
      if (
        (num !== '0' && param !== '.') ||
        (param === '.' && num.indexOf('.') === -1) ||
        (num === '0' && str.indexOf('0.') > -1)
      ) {
        if (arr.indexOf(str.charAt(len - 1)) !== -1 && arr.indexOf(param) !== -1) {
          // 若一开始输入内容为运算符,输入无效
          return;
        }
        this.inputShow.value += param; // 拼接输入内容
      } else {
        arr.push('%');
        if (param === '.') {
          // 若num中已有小数点,输入内容为小数点,视为无效
        } else if (!(arr.indexOf(param) !== -1)) {
          // 判断输入框内最后一个字符不为运算符
          this.inputShow.value = str.substring(0, str.length - nlen) + param; // 输入框内最后一串数字为0时,删除0拼接
        }
      }
    },
    clearValue() {
      // 清空输入框内容
      this.inputShow.value = '0';
    },
    calValue() {
      let str = this.inputShow.value;
      if (str.includes('÷0')) {
        this.inputShow.value = 'error';
        return;
      }

      // 替换运算符
      str = str.replace(/×/g, '*').replace(/÷/g, '/').replace(/%/g, '*0.01');

      // 检查连续运算符，避免错误输入
      const invalidOperatorsPattern = /[*/+-]{2,}/;
      if (invalidOperatorsPattern.test(str)) {
        this.inputShow.value = 'error';
        return;
      }

      // 处理所有数字和运算符的顺序正确性
      const validPattern = /^(\d+(\.\d+)?([*/+-]\d+(\.\d+)?)*|\d+(\.\d+)?[*/+-]\d+(\.\d+)?[*/+-]\d+(\.\d+)?)*$/;
      if (!validPattern.test(str)) {
        this.inputShow.value = 'error';
        return;
      }

      try {
        this.inputShow.value = this.eval(str);
      } catch (error) {
        console.log('error ===========> ', error);
        this.inputShow.value = 'error';
      }
    },
    eval(fn) {
      const Fn = Function;
      return this.fixFloatCalcRudely(new Fn(`return ${fn}`)());
    },
    fixFloatCalcRudely(num) {
      if (typeof num === 'number') {
        const str = num.toString();
        const match = str.match(/\.(\d*?)(9|0)\2{5,}(\d{1,5})$/);
        if (match != null) {
          return num.toFixed(match[1].length) - 0;
        }
      }
      return num;
    },
    squareValue() {
      // 平方计算
      const str = this.inputShow.value;
      this.inputShow.value = this.fixFloatCalcRudely(this.eval(str) ** 2);
    },
    radicalValue() {
      // 开根号计算
      const str = this.inputShow.value;
      this.inputShow.value = Math.sqrt(this.eval(str));
    },
    backValue() {
      // 删除键,删除单个字符
      const str = this.inputShow.value;
      if (str.length === 1) {
        this.inputShow.value = '0';
      } else {
        this.inputShow.value = str.slice(0, str.length - 1);
      }
    },
    oppositeValue() {
      // 正负号取值
      const str = this.inputShow.value;
      const num = `${parseInt(str.split('').reverse().join(''), 10)}`.split('').reverse().join(''); // 获取输入框内最后遗传数字
      const nlen = num.length;
      if (!Number.isNaN(parseInt(str.charAt(str.length - 1), 10)) && num !== 0) {
        // 当输入框末位字符为数字且最后一串数字不为0时,取正负
        this.inputShow.value = `${str.substring(0, str.length - nlen)}(-${num})`;
      }
    },
    eval(fn) {
      const Fn = Function; // 一个变量指向Function，防止有些前端编译工具报错
      return this.fixFloatCalcRudely(new Fn(`return ${fn}`)());
    },
    // 纠正0.1+0.2!=0.3的问题
    fixFloatCalcRudely(num) {
      if (typeof num === 'number') {
        const str = num.toString();
        const match = str.match(/\.(\d*?)(9|0)\2{5,}(\d{1,5})$/);
        if (match != null) {
          return num.toFixed(match[1].length) - 0;
        }
      }
      return num;
    },
  },
};
</script>
<style lang="scss" scoped>
._containers {
  width: 28em;
  padding-top: 20px;
  text-align: center;
  background: rgba(255, 255, 255, 1);
  box-shadow: 0px 0px 16px 0px rgba(0, 0, 0, 0.1);
  border-radius: 8px;
  // cursor: move;
  position: relative;

  #calculator {
    padding: 10px;
    -moz-border-radius: 3px;
    -webkit-border-radius: 3px;
    border-radius: 3px;
    // box-shadow: 0px 0px 10px #f2f2f2;
    // -moz-box-shadow: 0px 0px 10px #f2f2f2;
    // -webkit-box-shadow: 0px 0px 10px #f2f2f2;
    margin: 1.5em auto 0 auto;
    text-align: center;
  }

  #calculator #input-box {
    margin: 0;
    width: 187px;
    padding: 9px 5px;
    height: 14px;
    border: 1px solid #e5e5e5;
    border-radius: 3px;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    background: #fff;
    text-align: right;
    line-height: 14px;
    font-size: 12px;
    font-family: Verdana, Geneva, sans-serif;
    color: #666;
    outline: none;
    text-transform: uppercase;
  }

  #calculator #btn-list {
    width: 70%;
    overflow: hidden;
    margin: auto;
  }

  #calculator #btn-list .btn-radius {
    border-radius: 2px;
    -webkit-border-radius: 2px;
    -moz-border-radius: 2px;
    border: 1px solid #e5e5e5;
    background: -webkit-gradient(linear, 0 0, 0 100%, from(#f7f7f7), to(#ebebeb));
    background: -moz-linear-gradient(top, #f7f7f7, #ebebeb);
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#f7f7f7,endColorstr=#ebebeb,grandientType=1);
    line-height: 29px;
    text-align: center;
    text-shadow: 0px 1px 1px #fff;
    font-weight: bold;
    font-family: Verdana, Geneva, sans-serif;
    color: #666;
    float: left;
    margin-left: 11px;
    margin-top: 11px;
    font-size: 12px;
    cursor: pointer;
  }

  #calculator #btn-list .btn-radius:active {
    background: #f2f2f2;
  }

  #calculator #btn-list .clear-marginleft {
    margin-left: 0;
  }

  #calculator #btn-list .font-14 {
    font-size: 14px;
  }

  #calculator #btn-list .color-red {
    color: #ff5050;
  }

  #calculator #btn-list .color-blue {
    color: #fc8b09;
  }

  #calculator #btn-list .btn-30 {
    width: 46px;
    height: 29px;
  }

  #calculator #btn-list .btn-70 {
    width: 106px;
    height: 29px;
  }
}
</style>
